dockerfile 예시 및 이미지 빌드 – ssh 서버 및 편의 패키지 포함

일반적으로 개발사 등에서 제공되는 docker image 들은 운영에 필요한 최소한의 바이너리들만 담는 경우가 많기 때문에 컨테이너에 문제가 생기거나, 컨테이너 내부의 프로세스를 확인하고자 하는 경우에 ps 명령이 없어서 프로세스 확인이 불가능하거나, ping 명령이 없어서 연결 여부 확인이 안된다거나 하는 경우가 있을 수 있다. 또 docker 명령을 이용해 컨테이너에 진입하여 작업을 하는 것이 이래저래 불편해서 ssh의 아쉬움을 느끼는 경우도 왕왕 있을 것이다.

이 포스트에서는 특정한 도커 이미지에 운영에 편의를 위한 패키지들을 설치하고 SSH 서버도 추가하여 이미지를 새로 만들 것이다.

dockerfile 예제

실제 docker image build를 위한 예제이다.
세부 내용은 주석을 참고하면된다.

# base가 될 이미지 
# bitnami/jupyter-base-notebook
# 최신의 이미지에 append 하는 형태로 빌드하고자 한다면 latest tag 를 붙여준다.
# FROM haedongg.net/library/jupyter/pyspark-notebook:latest
FROM haedongg.net/library/jupyter/pyspark-notebook:spark-3.2.0

# 레이블. 없어도 된다. 
LABEL comment "essential tools & configuration"

# 아래 작업들을 수행할 계정 
# USER ACCOUNT 다음 라인은 별도로 USER를 변경하는 작업이 없다면 모두 ACCOUNT 계정으로 작업이 수행된다.
USER root

ENV DEBIAN_FRONTEND=noninteractive \
    TZ=Asia/Seoul


# 편의를 위해 기본적으로 필요한 것들
# 프록시를 사용하는 경우 apt-get 앞에 다음을 추가한다.
# RUN sudo https_proxy=PROXY_SERVER_HOST:PORT http_proxy=PROXY_SERVER_HOST:PORT
RUN apt-get update
RUN apt-get install -y openssh-server sudo procps curl vim git openssh-client telnet net-tools tcpdump htop --no-install-recommends 
# 컨테이너 이미지 파일의 크기를 줄이기 위해 apt 수행 중 생성된 임시 파일들을 삭제해준다.
RUN apt-get clean && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*


#### 여기부터 SSH 
RUN mkdir /var/run/sshd

# root password 변경, $PASSWORD를 변경한다.
RUN echo 'root:$PASSWORD' |  chpasswd

# ssh 설정 변경
# root 계정으로의 로그인을 허용한다. 아래 명령을 추가하지 않으면 root 계정으로 로그인이 불가능하다. 
RUN sed -ri 's/^#?PermitRootLogin\s+.*/PermitRootLogin yes/' /etc/ssh/sshd_config
# 응용 프로그램이 password 파일을 읽어 오는 대신 PAM이 직접 인증을 수행 하도록 하는 PAM 인증을 활성화
RUN sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config

RUN mkdir /root/.ssh
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
####여기까지 SSH

# sudo 설정
# 사용자 추가, $USER 가 사용자 명, $PASSWORD 가 패스워드이다.
RUN adduser --disabled-password --gecos "" $USER &&\ 
    echo '$USER:$PASSWORD' | chpasswd  &&\ 
    adduser $USER sudo &&\ 
    echo 'USER ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers


# user 변경
USER $USER

# alias를 추가하고 싶은 경우
RUN echo "alias ll='ls -lha'"  >>  /home/$USER/.bashrc


# pip 패키지 인스톨
# 프록시를 사용한다면 RUN https_proxy=http://PROXY_SERVER_HOST:PORT http_proxy=PROXY_SERVER_HOST:PORT
RUN  pip --trusted-host pypi.org --trusted-host files.pythonhosted.org install --no-cache-dir s3fs py4j pytz toml xgboost==1.5.1 lightgbm==3.3.1 scikit-learn==1.0.1 mlflow mlflow-skinny sqlalchemy alembic sqlparse  tqdm boto3

# 설정된 home directory의 권한 부여
RUN chown -R $USER /home/$USER

 

Build

#  docker  image    build     -t       $TARGET_DOCKER_IMAGE_NAME:tag           $dockerfile_location
docker image build -t haedongg.net/library/new_haedong_image:v0.1   .
docker image tag haedongg.net/library/new_haedong_image:v0.1  haedongg.net/library/new_haedong_image:latest

_-t 옵션 및 tag 옵션으로 지정하는 이미지 이름은 build에 사용한 원래 이미지의 이름, 경로와는 상관이 없다. 내가 사용하고자 하는 이름을 지정하면 된다.
단, local 이미지가 아닌 harbor나 docker hub 등의 외부 리포지터리에 업로드 하고자 한다면 정확한 이름을 지정해줘야 push가 가능하다._

Kubernetes #4-2. Kubernetes 클러스터 구축 – 단일 마스터노드 클러스터 생성 (offline, 폐쇄망)

[Kubernetes #1. 사전작업 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – 컨테이너 런타임 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – docker 설정 (offline, 폐쇄망)]
[Kubernetes #3. Kubernetes 바이너리 설치 (offline, 폐쇄망)]
[Kubernetes #4. Kubernetes 클러스터 구축 – image pull (offline, 폐쇄망)]
[Kubernetes #4-2. Kubernetes 클러스터 구축 – 단일 마스터노드 생성 (offline, 폐쇄망)]
[Kubernetes #4-3. Kubernetes 클러스터 구축 – worker node join (offline, 폐쇄망)]

kubeadm init

sudo kubeadm init –apiserver-advertise-address $MASTER_NODE_IP_ADDRESS –pod-network-cidr=10.244.0.0/16
명령을 수행하면 설치가 시작된다.
–apiserver-advertise-address : 마스터노드 IP
–pod-network-cidr : pod간 통신을 위한 내부 네트워크 CIDR 1사이더(Classless Inter-Domain Routing, CIDR)는 클래스 없는 도메인 간 라우팅 기법으로 1993년 도입되기 시작한, 최신의 IP 주소 할당 방법이다. 사이더는 기존의 IP 주소 할당 방식이었던 네트워크 클래스를 대체하였다. 사이더는 IP 주소의 영역을 여러 네트워크 영역으로 나눌 때 기존방식에 비해 유연성을 더해준다. 특히 다음과 같은 장점이 있다.
급격히 부족해지는 IPv4 주소를 보다 효율적으로 사용하게 해준다.
접두어를 이용한 주소 지정 방식을 가지는 계층적 구조를 사용함으로써 인터넷 광역 라우팅의 부담을 줄여준다.

sudo    kubeadm   init   --apiserver-advertise-address $MASTER_NODE_IP_ADDRESS --pod-network-cidr=10.244.0.0/16

...전략...
[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.192.168:6443 --token abcdefg.8rpr4mfmetbabcde --discovery-token-ca-cert-hash sha256:3a12345caaef12334567890cd3953d1234c3904ab70a8b949f32d6df12345
  • /etc/kubernetes/admin.conf 에는 마스터노드의 kube-proxy 관련 정보가 들어있다. mkdir 부터 시작하는 명령을 수행해줘야 kubectl 명령을 사용할 수 있다.
  • 마지막 kubeadm join 명령은 worker 노드를 추가하기 위한 명령이다. worker 노드가 될 서버에kubernetes 관련 패키지(kueadm,kubectl,kubelet 및 image 등)를 설치한 뒤 수행해주면 worker 노드로 클러스터의 멤버가 된다. token 관련 값은 24시간의 유효시간이 있으므로 나중에 클러스터 멤버로 join 하려면 새로 새로 발행해야 한다.

확인

init 스크립트가 완료되고 kubernetes config 관련 설정을 마쳤다면 kubectl 명령을 사용할 수 있다. 다음 명령을 통해 상태를 확인한다.

kubectl get nodes
NAME      STATUS     ROLES                  AGE   VERSION
centos7   NotReady   control-plane,master   20s   v1.23.5

현재 노드의 status 가 NotReady로 나오지만 정상적으로 설정 된 것이다.

Kubernetes #4. Kubernetes 클러스터 구축 – image pull (offline, 폐쇄망)

[Kubernetes #1. 사전작업 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – 컨테이너 런타임 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – docker 설정 (offline, 폐쇄망)]
[Kubernetes #3. Kubernetes 바이너리 설치 (offline, 폐쇄망)]
[Kubernetes #4. Kubernetes 클러스터 구축 – image pull (offline, 폐쇄망)]
[Kubernetes #4-2. Kubernetes 클러스터 구축 – 단일 마스터노드 생성 (offline, 폐쇄망)]
[Kubernetes #4-3. Kubernetes 클러스터 구축 – worker node join (offline, 폐쇄망)]

이전 포스트에서 설치한 kubeadm을 위해 클러스터를 생성할 때 필요한 몇 가지 이미지가 존재한다. 폐쇄망 환경에서는 해당 이미지를 가져올 수 없기 때문에 외부 네트워크 연결이 가능한 환경에서 이미지를 가져온(pull) 다음 클러스터를 생성할 곳에 넣어주는(push) 과정이 필요하다.

Image pull

  • image pull 외부 네트워크 연결이 가능한 환경에서 수행한다.
kubeadm config images pull
[config/images] Pulled k8s.gcr.io/kube-apiserver:v1.23.5
[config/images] Pulled k8s.gcr.io/kube-controller-manager:v1.23.5
[config/images] Pulled k8s.gcr.io/kube-scheduler:v1.23.5
[config/images] Pulled k8s.gcr.io/kube-proxy:v1.23.5
[config/images] Pulled k8s.gcr.io/pause:3.6
[config/images] Pulled k8s.gcr.io/etcd:3.5.1-0
[config/images] Pulled k8s.gcr.io/coredns/coredns:v1.8.6
  • 이미지 저장 위의 7개 이미지를 export하여 압축파일로 저장한다. (별도의 결과 메시지는 출력되지 않는다)
docker image save k8s.gcr.io/kube-apiserver:v1.23.5             > kube-apiserver.tgz
docker image save k8s.gcr.io/kube-controller-manager:v1.23.5    > kube-controller-manager.tgz
docker image save k8s.gcr.io/kube-scheduler:v1.23.5             > kube-scheduler.tgz         
docker image save k8s.gcr.io/kube-proxy:v1.23.5                 > kube-proxy.tgz                 
docker image save k8s.gcr.io/pause:3.6                          > pause.tgz                     
docker image save k8s.gcr.io/etcd:3.5.1-0                       > etcd.tgz
docker image save k8s.gcr.io/coredns/coredns:v1.8.6             > coredns.tgz 

이미지 추출이 완료되면 대상 SCP 명령 등을 이용하여 해당 파일들을 복사한다.

Image push

  • 대상 서버는 인터넷에 연결이 불가능하므로 복사한 image를 push 해줘야 한다.
docker load    <    kube-apiserve
docker load    <    kube-controll
docker load    <    kube-schedule
docker load    <    kube-proxy.tg
docker load    <    pause.tgz    
docker load    <    etcd.tgz     
docker load    <    coredns.tgz  
  Loaded image: k8s.gcr.io/kube-apiserver:v1.23.5  
  Loaded image: k8s.gcr.io/kube-controller-manager:
  Loaded image: k8s.gcr.io/kube-scheduler:v1.23.5  
  Loaded image: k8s.gcr.io/kube-proxy:v1.23.5      
  Loaded image: k8s.gcr.io/pause:3.6               
  Loaded image: k8s.gcr.io/etcd:3.5.1-0            
  Loaded image: k8s.gcr.io/coredns/coredns:v1.8.6
  • 확인
 docker images |grep k8s.gcr.io
k8s.gcr.io/kube-apiserver                                        v1.23.5            3fc1d62d6587   2 weeks ago    135MB
k8s.gcr.io/kube-proxy                                            v1.23.5            3c53fa8541f9   2 weeks ago    112MB
k8s.gcr.io/kube-controller-manager                               v1.23.5            b0c9e5e4dbb1   2 weeks ago    125MB
k8s.gcr.io/kube-scheduler                                        v1.23.5            884d49d6d8c9   2 weeks ago    53.5MB
k8s.gcr.io/etcd                                                  3.5.1-0            25f8c7f3da61   5 months ago   293MB
k8s.gcr.io/coredns/coredns                                       v1.8.6             a4ca41631cc7   6 months ago   46.8MB
k8s.gcr.io/pause                                                 3.6                6270bb605e12   7 months ago   683kB

 

모든 클러스터 적용

Master node 및 Worker node로 설정 될 모든서버에서 위 작업을 수행해준다.

 

 

 

Kubernetes #3. Kubernetes 바이너리 설치 (offline, 폐쇄망)

[Kubernetes #1. 사전작업 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – 컨테이너 런타임 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – docker 설정 (offline, 폐쇄망)]
[Kubernetes #3. Kubernetes 바이너리 설치 (offline, 폐쇄망)]
[Kubernetes #4. Kubernetes 클러스터 구축 – image pull (offline, 폐쇄망)]
[Kubernetes #4-2. Kubernetes 클러스터 구축 – 단일 마스터노드 생성 (offline, 폐쇄망)]
[Kubernetes #4-3. Kubernetes 클러스터 구축 – worker node join (offline, 폐쇄망)]

Yum repository를 추가해서 설치하는 방법, 바이너리를 직접 다운로드 한 다음 스크립트를 생성하는 방법, 두 가지가 있다

이 포스트의 작업은 쿠버네티스 클러스터에 포함하는 모든 노드에서 수행해야 한다.

      

패키지 매니저를 이용한 설치

CentOS yum repository 추가

sudo cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl
EOF

Ubunt

sudo apt-get install -y apt-transport-https ca-certificates curl
# 구글 클라우드의 공개 signing 키 다운로드
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
# Kubernetes 리포지터리 추가
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

      

패키지 설치

CentOS

sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes

Ubuntu

sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

      

서비스 등록 및 활성화

CentOS, Ubuntu 동일

sudo systemctl enable kubelet.service

sudo systemctl start kubelet.service

      

      

바이너리 다운로드를 통한 설치

CNI 플러그인1yum 등을 이용해서 설치하는 경우 의존성 패키지로 설치된다., kubeadm, kubelet, kubectl 을 설치한다.

아래 설명에서 curl 대신 wget을 이용하거나, 작업중인 PC에서 다운로드 후 업로드 하는 방법으로 대체해도 무방하다.

CNI 플러그인 설치

CNI_VERSION="v0.8.2" 
sudo mkdir -p /opt/cni/bin
curl -L "https://github.com/containernetworking/plugins/releases/download/${CNI_VERSION}/cni-plugins-linux-amd64-${CNI_VERSION}.tgz" | sudo tar -C /opt/cni/bin -xz
#curl -LO 옵션으로 다운로드 후 별도로 압축을 해제해도 된다. 이 경우 압축 해제된 파일을 /opt/cni/bin 디렉토리로 이동 해야 한다.

clictl 설치

DOWNLOAD_DIR=/usr/local/bin
sudo mkdir -p $DOWNLOAD_DIR

kubeadm, kubelet, kubectl 바이너리 설치

RELEASE="$(curl -sSL https://dl.k8s.io/release/stable.txt)" 
cd $DOWNLOAD_DIR
sudo curl -L --remote-name-all https://storage.googleapis.com/kubernetes-release/release/${RELEASE}/bin/linux/amd64/{kubeadm,kubelet,kubectl}
sudo chmod +x {kubeadm,kubelet,kubectl}

서비스 스크립트 다운로드

RELEASE_VERSION="v0.4.0" 
curl -sSL "https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubelet/lib/systemd/system/kubelet.service" | sed "s:/usr/bin:${DOWNLOAD_DIR}:g" | sudo tee /etc/systemd/system/kubelet.service
sudo mkdir -p /etc/systemd/system/kubelet.service.d
curl -sSL "https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubeadm/10-kubeadm.conf" | sed "s:/usr/bin:${DOWNLOAD_DIR}:g" | sudo tee /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

 

서비스 스크립트 생성 (위 스크립트 다운로드 방법 대체)

sudo vi /etc/systemd/system/kubelet.service
# 아래 내용을 붙여넣기 한다.
[Unit]
Description=kubelet: The Kubernetes Node Agent
Documentation=https://kubernetes.io/docs/home/
Wants=network-online.target
After=network-online.target

[Service]
ExecStart=/usr/bin/kubelet
Restart=always
StartLimitInterval=0
RestartSec=10

[Install]
WantedBy=multi-user.target
sudo vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
# 아래 내용을 붙여넣기 한다.
# Note: This dropin only works with kubeadm and kubelet v1.11+
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
# This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically
EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
# This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use
# the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file.
EnvironmentFile=-/etc/default/kubelet
ExecStart=
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS

 

서비스 등록 및 시작

systemctl enable kubelet.service
systemctl start kubelet.service

 

 

 

 

Kubernetes #2-2. 사전작업 – docker 설정 (offline, 폐쇄망)

[Kubernetes #1. 사전작업 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – 컨테이너 런타임 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – docker 설정 (offline, 폐쇄망)]
[Kubernetes #3. Kubernetes 바이너리 설치 (offline, 폐쇄망)]
[Kubernetes #4. Kubernetes 클러스터 구축 – image pull (offline, 폐쇄망)]
[Kubernetes #4-2. Kubernetes 클러스터 구축 – 단일 마스터노드 생성 (offline, 폐쇄망)]
[Kubernetes #4-3. Kubernetes 클러스터 구축 – worker node join (offline, 폐쇄망)]

망분리 환경에서 proxy등을 통한 외부 연결이 가능하거나, 망 내부적으로 proxy를 통해 통신하는 경우 proxy 설정이 필요하다.
linux OS 레벨에서는 .bash_profile 등에 proxy 변수를 등록하는 것으로 처리가 가능하지만 docker 런타임은 별도로 proxy 정보를 정의해 줘야 한다

이 포스트의 작업은 쿠버네티스 클러스터에 포함하는 모든 노드에서 수행해야 한다.

     

Docker Proxy 설정

서비스 설정 (docker login 등의 작업 에 사용된다.)

[haedong@haedong:~:]$ sudo /lib/systemd/system/docker.service
전략...
# [service] 섹션에 아래 추가
Environment="HTTP_PROXY=http://120.121.122.123:8080" 
Environment="HTTPS_PROXY=https://120.121.122.123:8080" 
Environment="NO_PROXY=.haedong.net,localhost,127.0.0.1/8,192.168.0.0/16,.local" 
[haedong@haedong:~:]$ sudo systemctl daemon-reload
[haedong@haedong:~:]$ sudo systemctl restart docker.service

컨테이너 설행 시 변수로 전달

[haedong@haedong:~]$ docker run \
-e http_proxy=http://120.121.122.123:8080 \
-e https_proxy https://120.121.122.123:8080 \
-e no_proxy .haedong.net,localhost,127.0.0.1/8,192.168.0.0/16,.local \
CONTAINER_NAME

이미지 빌드 시 포함

ENV PATH /home/haedong/bin:$PATH
ENV LD_LIBRARY_PATH /lib:/lib64:$LD_LIBRARY_PATH
...중략...
# 아래 내용 추가
ENV http_proxy http://120.121.122.123:8080
ENV https_proxy https://120.121.122.123:8080
ENV no_proxy .haedong.net,localhost,127.0.0.1/8,192.168.0.0/16,.local

     

Docker root directory 변경

pull 한 image나 컨테이너 임시 데이터 등이 저장되는 디렉토리이다. 기본 값은 /var/lib/docker 인데, /var directory가 포함된 파티션의 크기가 작거나 하는 경우 disk full 로 인해 문제를 야기할 수 있다.

현재 docker root 확인

docker info | grep "Docker Root Dir" 

 Docker Root Dir: /var/lib/docker

#docker volume inspect my-vol

준비

docker root dirctory로 사용할 디스크를 확정하고 파티션 생성, 마운트 등의 작업을 마친다.
sudo systemctl stop docker.service 명령으로 서비스를 중지하고(시간이 걸릴 수 있다. 프로세스가 완전히 사라졌는지 확인하도록 하자) 이전의 docker 파일들을 대상 디렉토리로 복사한다.

mkdir /data
cp -rp /var/lib/docker /data

     

서비스 수정

sudo vi /usr/lib/systemd/system/docker.service
# Service 섹션에 ExecStart= 로 시작하는 줄을 수정한다.
# ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --data-root=/data
sudo systemctl daemon-reload
sudo systemctl restart docker.service

     

cgroup driver 변경

현재 상태 확인

sudo docker info | grep cgroup
 Cgroup Driver: cgroupfs

서비스 수정

sudo vi /etc/systemd/system/docker.service

# ExecStart 로 시작하는 줄에  --exec-opt native.cgroupdriver=systemd 추가
# ExecStart=/usr/bin/dockerd -g /home/data/ -H fd:// --containerd=/run/containerd/containerd.sock
ExecStart=/usr/bin/dockerd -g /home/data/ -H fd:// --containerd=/run/containerd/containerd.sock --exec-opt native.cgroupdriver=systemd
sudo systemctl daemon-reload
sudo systemctl restart docker.service

Kubernetes #2-2. 사전작업 – 컨테이너 런타임 (offline, 폐쇄망)

[Kubernetes #1. 사전작업 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – 컨테이너 런타임 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – docker 설정 (offline, 폐쇄망)]
[Kubernetes #3. Kubernetes 바이너리 설치 (offline, 폐쇄망)]
[Kubernetes #4. Kubernetes 클러스터 구축 – image pull (offline, 폐쇄망)]
[Kubernetes #4-2. Kubernetes 클러스터 구축 – 단일 마스터노드 생성 (offline, 폐쇄망)]
[Kubernetes #4-3. Kubernetes 클러스터 구축 – worker node join (offline, 폐쇄망)]

쿠버네티스는 ‘컨테이너를 관리’ 하는 녀석이다. 즉, 쿠버네티스만으로는 아무 것도 할 수 없다는 이야기. 컨테이너 실행을 위해 런타임이 필요하다. Docker, Containerd, CRI-O 등이 있다.
이 포스트에서는 docker를 기준으로 설명한다.

외부에서 repo 파일을 다운로드 받아서 폐쇄망의 클러스터에 복사하거나, –downloadonly 등의 옵션으로 패키지를 다운로드 해서 복사 한다음 설치해야 한다.

이 포스트의 작업은 쿠버네티스 클러스터에 포함하는 모든 노드에서 수행해야 한다.

 

이전 버전의 docker 제거

CentOS (CentOS7 기준)

sudo yum remove docker docker-client docker-client-latest docker-common \
                  docker-latest docker-latest-logrotate docker-logrotate docker-engine

Ubuntu (Ubuntu18 기준)

sudo apt-get remove docker docker-engine docker.io containerd runc

 

설치를 위한 패키지와 repository 등록

CentOS

sudo yum install -y yum-utils
# yum-config-manager를 위한 패키지

sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# yum-utils 패키지 설치를 생략하고 docker-ce.repo 파일을 다운로드 받아서 /etc/yum.repos.d/에 복사해도 된다.

sudo yum clean all
# yum 캐시 정리 캐시 파일이 너무 크거나 문제가 있는 경우 sudo rm -rf /var/cache/yum 명령 수행

sudo yum repolist
# 패키지 목록 업데이트

Ubuntu

sudo apt-get update
# apt 패키지 목록 업데이트

sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release
# 패키지 설치 및 rpository 업데이트 등을 위한 패키지 설치

sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# gpg key 등록

sudo echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# docker repository 등록

sudo apt-get update

 

Docker 엔진설치

CentOS

sudo yum -y install docker-ce docker-ce-cli containerd.io

Ubuntu

sudo apt-get install docker-ce docker-ce-cli containerd.io

 

서비스 시작 및 활성화

CentOS / Ubuntu 동일

sudo systemctl enable docker.service
# 서비스 활성화 (부팅 시 자동 시작)

sudo systemctl start docker.service
# 서비스 시작

 

특정 버전을 설치하자 하는 경우

# CentOS
yum list docker-ce --showduplicates | sort -r
 sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli- containerd.io

	
#Ubuntu
apt-cache madison docker-ce
 docker-ce | 5:20.10.8~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
 docker-ce | 5:20.10.7~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
 docker-ce | 5:20.10.6~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
 docker-ce | 5:20.10.5~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
 docker-ce | 5:20.10.4~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
 docker-ce | 5:20.10.3~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
 docker-ce | 5:20.10.2~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
 docker-ce | 5:20.10.1~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
 docker-ce | 5:20.10.0~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
...후략
출력되는 목록에서 버전 확인 후 설치
sudo apt-get install docker-ce= docker-ce-cli= containerd.io

Kubernetes #1. 사전작업 (offline, 폐쇄망)

[Kubernetes #1. 사전작업 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – 컨테이너 런타임 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – docker 설정 (offline, 폐쇄망)]
[Kubernetes #3. Kubernetes 바이너리 설치 (offline, 폐쇄망)]
[Kubernetes #4. Kubernetes 클러스터 구축 – image pull (offline, 폐쇄망)]
[Kubernetes #4-2. Kubernetes 클러스터 구축 – 단일 마스터노드 생성 (offline, 폐쇄망)]
[Kubernetes #4-3. Kubernetes 클러스터 구축 – worker node join (offline, 폐쇄망)]

쿠버네티스 공식 홈페이지의 가이드를 따르면 쉽게 설치할 수 있다.
하지만 경우에 따라 외부 연결이 불가능한 폐쇄망 등에 설치해야 하는 경우를 가정하여 설치하는 방법을 설명한다. (물론 이 방법도 쿠버네티스 공식 홈페이지에 잘 설명되어있다.)

기본적으로 쿠버네티스 클러스터는 노드간 통신에 별도의 네트워크를 사용한다.
(별도의 물리적 변경이 아닌 가상 환경) 이를 위해 브릿지 관련 설정을 변경한다.

이 포스트의 작업은 쿠버네티스 클러스터에 포함하는 모든 노드에서 수행해야 한다.

브릿지 네트워크 관련 설정 변경

[haedong@haedongg.net:~]$ sudo cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
[haedong@haedongg.net:~]$ sudo cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
[haedong@haedongg.net:~]$ sudo sysctl --system
[haedong@haedongg.net:~]$ sudo sysctl -p 
net.ipv4.tcp_keepalive_time = 160
net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.tcp_syncookies = 1
vm.min_free_kbytes = 524288
...중략
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-arptables = 1
...생략

SELINUX 해제

[haedong@haedongg.net:~]$ vi /etc/selinux/config
...중략...
# 기본값은 SELINUX=enforced disabled로 수정한다.
SELINUX=disabled 
...생략

 

swap 메모리 해제

swap 여부 확인

[haedong@haedongg.net:~]$ free -g
              total        used        free      shared  buff/cache   available
Mem:             62           3           0           0          57          57
Swap:            99           0          99

swap 해제

[haedong@haedongg.net:~]$ swapoff -a

해제 확인

[haedong@haedongg.net:~]$ free -g
              total        used        free      shared  buff/cache   available
Mem:             62           3           0           0          57          57
Swap:             0           0           0

fstab 수정 ( swap 파티션이 마운트되지 않도록 설정)

[haedong@haedongg.net:~]$ sudo vi /etc/fstab
/dev/mapper/centos-root /                       xfs     defaults        0 0
UUID=111f15c1-7697-4597-1234-b7f231009876 /boot                   xfs     defaults        0 0
#/dev/mapper/centos-home /home                   xfs     defaults        0 0
# 아래 줄을 주석처리 한다.
#/dev/mapper/centos-swap swap                    swap    defaults        0 0

 

hostname 과 hosts 파일 수정

쿠버네티스는 기본적으로 kubeadm init 시 hostname을 참조한다. 별도의 DNS를 사용하지 않는다면 /etc/hosts 파일에 호스트 명과 IP 정보를 적어준다.

[haedong@haedongg.net:~]$ vi /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

# 현재 서버의 정보가 없을 경우 다음 줄 추가 
192.168.192.168 haedongg.net