Ubuntu(zsh) 이미지 실행하는 방법

|

Docker 컨테이너에 zsh 설치하기

이미 빌드된 이미지 사용하기

이미 Docker Hub에 위 이미지가 올라가 있기 때문에, 별도의 과정 필요없이 아래 명령어로 바로 사용할 수 있습니다.

$ docker run -it snowdeer/ubuntu-22p04 zsh

이미지 생성하는 방법

위의 이미지를 생성하는 방법입니다. Dockerfile을 이용해서 생성할 수도 있지만, 실제 Ubuntu를 사용하면서 신규 패키지를 설치하는 경우도 있기 때문에 이번에는 컨테이너에 다양한 패키지를 직접 설치한다음 이미지로 만드는 방법으로 실행해보았습니다.

zsh가 설치된 Docker 이미지는 이미 Docker Hub에서 받을 수 있지만, 제가 개인적으로 사용하는 Ubuntu 이미지에 zsh를 설치해서 사용하는 것을 더 좋아합니다.

기본 ubuntu 이미지에 zsh만 설치했을 때는 몇 가지 문제(ex. Locale 설정 등)가 발생해서 그 해결 방법을 아래와 같이 포스팅합니다.

Ubuntu 이미지 다운로드

# 최신 Ubuntu 이미지 다운로드(현 시점 기준 22.04 버전)
$ docker pull ubuntu

$ docker run -it ubuntu

필요 패키지 설치

Docker 컨테이너 속의 터미널에서는 다음과 같이 입력합니다.

$ apt update

# vi를 써도 되지만 개인적으론 nano가 더 편해서 nano도 설치
$ apt install -y git curl nano zsh

# 생략해도 되지만 network 관련 유틸리티이기 때문에 그냥 설치 
$ apt install -y iputils-ping net-tools iproute2 dnsutils

# oh-my-zsh 설치
$ sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"

... 
Time to change your default shell to zsh:
Do you want to change your default shell to zsh? [Y/n] y

ZSH 설정 편집

nano ~/.zshrc 명령어로 편집기를 실행해서 ZSH_THEME="robbyrussell" 부분만 ZSH_THEME="agnoster"으로 수정합니다.

이 상태에서 zsh 명령어로 zshell을 실행하면 아래와 같은 오류가 발생합니다.

$ zsh

(anon):12: character not in range

ZSH Locale 문제 해결

이 문제는 Locale 때문에 발생하는 문제로 아래와 같이 해결할 수 있습니다.

$ apt install -y locales

$ locale-gen en_US.UTF-8

자, 제가 개인적으로 즐겨 사용하는 ubuntu 이미지가 생성 완료되었습니다. 이 상태에서 해당 컨테이너의 내용으로 이미지를 만들어줍니다. (컨테이너 터미널 외부에서 입력합니다.)

Docker 이미지 commit

# 먼저 컨네이터의 ID를 확인합니다.
$ docker ps -a
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS                     PORTS     NAMES
d0b9b5314e29   ubuntu    "/bin/bash"   8 minutes ago   Exited (0) 2 seconds ago             adoring_carson

$ docker commit d0b9 snowdeer/ubuntu-22p04
sha256:b4a5a887e027af8a49062c67e2a53ea6cac8fd0c22d92a013ec2aba3b40896dc

$ docker images
REPOSITORY                    TAG       IMAGE ID       CREATED         SIZE
snowdeer/ubuntu-22p04         latest    b4a5a887e027   3 seconds ago   226MB

Docker Hub에 업로드

$ docker push snowdeer/ubuntu-22p04
Using default tag: latest
The push refers to repository [docker.io/snowdeer/ubuntu-22p04]
f5048f19797c: Pushed
c5ca84f245d3: Pushed
latest: digest: sha256:206d44f8646bb6bd041728531b74e193f325c340c8537b4881a3daf2f0522349 size: 741

Minikube에 Application Deploy 방법

|

Minikube에 Application Deploy 방법

Service

아래와 같이 샘플 Service를 생성할 수 있습니다.

$ kubectl create deployment hello-minikube --image=kicbase/echo-server:1.0

deployment.apps/hello-minikube created
$ kubectl expose deployment hello-minikube --type=NodePort --port=8080

service/hello-minikube exposed

잠시후 다음 명령어를 통해 위에서 생성한 hello-minikube 서비스 상태를 확인할 수 있습니다.

$ kubectl get services hello-minikube

NAME             TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
hello-minikube   NodePort   10.105.140.39           8080:30634/TCP   59s
</pre>

여기서 실제 브라우저로 동작을 확인하고 싶으면 아래 명령어를 실행하면 됩니다.

$ minikube service hello-minikube

|-----------|----------------|-------------|---------------------------|
| NAMESPACE |      NAME      | TARGET PORT |            URL            |
|-----------|----------------|-------------|---------------------------|
| default   | hello-minikube |        8080 | http://192.168.49.2:30634 |
|-----------|----------------|-------------|---------------------------|
🏃  Starting tunnel for service hello-minikube.
|-----------|----------------|-------------|------------------------|
| NAMESPACE |      NAME      | TARGET PORT |          URL           |
|-----------|----------------|-------------|------------------------|
| default   | hello-minikube |             | http://127.0.0.1:53680 |
|-----------|----------------|-------------|------------------------|
🎉  Opening service default/hello-minikube in default browser...
❗  Because you are using a Docker driver on darwin, the terminal needs to be open to run it.
그러면 자동으로 브라우저가 열리며, `hello-minikube` 페이지를 볼 수 있습니다. ### Port forwarding
$ kubectl port-forward service/hello-minikube 7080:8080

Forwarding from 127.0.0.1:7080 -> 8080
Forwarding from [::1]:7080 -> 8080
이 경우에는 http://localhost:7080/ 주소에서 위에서 만든 웹페이지를 확인할 수 있습니다. ## LoadBalancer
$ kubectl create deployment balanced --image=kicbase/echo-server:1.0

deployment.apps/balanced created
$ kubectl expose deployment balanced --type=LoadBalancer --port=8080

service/balanced exposed
다른 터미널 창을 열고 아래 명령어를 이용해서 `tunnel`을 실행해서 `balanced` 배포 대상의 routable IP를 생성해줍니다.
$ minikube tunnel

✅  Tunnel successfully started
📌  NOTE: Please do not close this terminal as this process must stay alive for the tunnel to be accessible ...
🏃  Starting tunnel for service balanced.
$ kubectl get services balanced

NAME       TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
balanced   LoadBalancer   10.99.117.109   127.0.0.1     8080:31198/TCP   83s

# 만약 위에서 `tunnel`을 실행하지 않았다면 아래와 같이 출력됩니다.
$ kubectl get services balanced

NAME       TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
balanced   LoadBalancer   10.99.117.109        8080:31198/TCP   2m41s
</pre>

그리고 브라우저에서 `http://127.0.0.1:8080`에 접속해서 위의 `EXTERNAL-IP`가 잘 작동하는지 확인할 수 있습니다.

## Ingress

Ingress를 사용하기 위해서는 아래 명령어로 minikube에 addon을 설치해줍니다.

$ minikube addons enable ingress

💡  ingress is an addon maintained by Kubernetes. For any concerns contact minikube on GitHub.
You can view the list of minikube maintainers at: https://github.com/kubernetes/minikube/blob/master/OWNERS
💡  After the addon is enabled, please run "minikube tunnel" and your ingress resources would be available at "127.0.0.1"
    ▪ Using image registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230407
    ▪ Using image registry.k8s.io/ingress-nginx/controller:v1.8.1
    ▪ Using image registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230407
🔎  Verifying ingress addon...
🌟  The 'ingress' addon is enabled
$ kubectl apply -f https://storage.googleapis.com/minikube-site-examples/ingress-example.yaml

pod/foo-app created
service/foo-service created
pod/bar-app created
service/bar-service created
ingress.networking.k8s.io/example-ingress created
#### ingress-example.yaml 위 파일을 브라우저 등으로 다운로드해보면 아래와 같은 내용이 입력되어 있는 것을 확인할 수 있습니다.
kind: Pod
apiVersion: v1
metadata:
  name: foo-app
  labels:
    app: foo
spec:
  containers:
    - name: foo-app
      image: 'kicbase/echo-server:1.0'
---
kind: Service
apiVersion: v1
metadata:
  name: foo-service
spec:
  selector:
    app: foo
  ports:
    - port: 8080
---
kind: Pod
apiVersion: v1
metadata:
  name: bar-app
  labels:
    app: bar
spec:
  containers:
    - name: bar-app
      image: 'kicbase/echo-server:1.0'
---
kind: Service
apiVersion: v1
metadata:
  name: bar-service
spec:
  selector:
    app: bar
  ports:
    - port: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
spec:
  rules:
    - http:
        paths:
          - pathType: Prefix
            path: /foo
            backend:
              service:
                name: foo-service
                port:
                  number: 8080
          - pathType: Prefix
            path: /bar
            backend:
              service:
                name: bar-service
                port:
                  number: 8080
---
### Ingress 확인
$ kubectl get ingress

NAME              CLASS   HOSTS   ADDRESS        PORTS   AGE
example-ingress   nginx   *       192.168.49.2   80      48s
다시 새로운 터미널을 열고 `minikube tunnel` 명령어를 이용해서 tunnel을 실행한다음, 브라우저에서는 `http://127.0.0.1/foo` 또는 `http://127.0.0.1/bar`로 ingress 및 LoadBalancer가 실행되고 있는 것을 확인할 수 있습니다. ## Reference - https://minikube.sigs.k8s.io/docs/start/