Kubernetes ConfigMap ve Secret Nedir?
Kubernetes ConfigMap ve Secret, uygulamalarınızın yapılandırma bilgilerini ve hassas verilerini güvenli bir şekilde saklamak ve uygulamalarınıza iletmek için kullanılan Kubernetes nesneleridir.
ConfigMap, uygulama yapılandırma bilgilerini depolamak ve paylaşmak için kullanılırken, Secret'ler hassas verileri (parolalar, API anahtarları, sertifikalar vb.) korumak için kullanılır. Bu yazıda, Kubernetes ConfigMap ve Secret kavramlarını daha ayrıntılı olarak ele alacak ve nasıl kullanıldıklarını anlatacağız.
1. ConfigMap Nedir?
ConfigMap, bir uygulamanın yapılandırma bilgilerini key-value çifti şeklinde depolamak için kullanılan bir Kubernetes kaynağıdır. ConfigMap'ler genellikle metin tabanlı verileri içerir. Uygulama pod'larına bu yapılandırma bilgilerini enjekte edebilirsiniz.

ConfigMap içinde oluşturduğunuz key-value configler, bir Pod'a environment variable veya özel bir volume olarak tanımlanabilir. Her birini detaylıca inceleyeceğiz.

Bir uygulamanın bir ConfigMap'i nasıl kullandığından bağımsız olarak, yapılandırmaların ayrı bir bağımsız nesnede olması, Pod manifestinizi değiştirmeden her biri farklı bir ortam için (development, test, QA, production vb.) aynı ada sahip ConfigMaps kullanmanıza olanak tanır. Pod'lar, ConfigMap'e adıyla başvurdukları için, hepsinde aynı Pod manifestini kullanırken her ortamda farklı bir yapılandırma kullanabilirsiniz.

1.1. ConfigMap Nasıl Oluşturulur?
Kubernetes'te ConfigMap oluşturmak için hem YAML hem de kubectl komutunu kullanabilirsiniz. Her iki yönteme de bakalım.
1.1.1 YAML Manifest Dosyasıyla ConfigMap Oluşturmak
YAML manifest dosyasıyla ConfigMap oluşturmak için aşağıdaki örneği kullanabilirsiniz.
apiVersion: v1
kind: ConfigMap
metadata:
name: my-configmap
data:
key1: value1
key-2: value2
counter: "5"
game.properties: |
enemy.types=aliens,monsters
player.maximum-lives=5
binaryData:
key3: L3Jvb3QvMTAw dataparametresi alanında tüm key-value config çiftlerinizi oluşturabilirsiniz.key1vekey2property-like key'lerdir.|işareti ile multi-line configler oluşturabilirsiniz. Bu config tipine file-like key'ler denir.- Eğer değerleriniz UTF-8 olmayan karakterler içeriyorsa
binaryDataparametresi alanında değerlerinizi base64 formatında ekleyebilirsiniz.
Bu YAML dosyasını kullanarak ConfigMap'i oluşturmak için aşağıdaki komutu kullanabilirsiniz:
kubectl apply -f configmap.yaml1.1.2 Kubectl Komutuyla ConfigMap Oluşturmak
Imperative methodla kubectl komutunu kullanarak ConfigMap oluştururken birçok senaryomuz mevcut. Tüm bu seçeneklere tek tek bakalım.
--from-literalargümanını kullanarak key-value config oluşturabiliriz. Tek bir komutta birden fazla config oluşturabilirsiniz.
kubectl create configmap my-configmap --from-literal=key1=value1 --from-literal=blog-name="Kerteriz Blog" --from-literal=blog-schema="https://"--from-fileargümanını kullanarak bir dosya içeriğinden config oluşturabilirsiniz. Eğer key belirtmezseniz, key dosya adı olarak belirlenir.
kubectl create configmap my-configmap --from-file=config-file.conf --from-file=file-config=config-file2.txt--from-fileargümanını kullanarak sadece dosya değil bir dizinde belirtebilirsiniz. Böylece o dizin altında yer alan tüm dosyalar için configler oluşturulmuş olur.
kubectl create configmap my-configmap --from-file=/var/config-dir/Son olarak tüm bu yöntemleri tek bir komut içerisinde aynı anda kullanabilirsiniz. Örneğin aşağıdaki komut tüm yöntemleri aynı anda kullanmanıza olanak sağlar.
kubectl create configmap my-config
➥ --from-file=foo.json
➥ --from-file=bar=foobar.conf
➥ --from-file=config-opts/
➥ --from-literal=some=thingBu komutu aşağıdaki gibi bir şemaya dökebiliriz.

1.2. ConfigMap Nasıl Kullanılır?
Kubernetes ConfigMap'leri kullanarak bir Pod'un yapılandırma bilgilerini belirtmek için birkaç farklı yöntem vardır. Tüm bu methodları tek tek inceleyelim
1.2.1 Environment Variable Olarak Kullanmak
ConfigMap configlerini kullanmanın en basit yolu, onları environment variable olarak container'lara geçmektir. Pod konfigürasyonunda env bölümünü kullanarak valueFrom parametresi ile nasıl environment variable tanımlayabileceğimizi aşağıdaki örnekte görebilirsiniz.
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: my-image
env:
- name: KEY1
valueFrom:
configMapKeyRef:
name: my-configmap
key: key1
- name: KEY2
valueFrom:
configMapKeyRef:
name: my-configmap
key: key2
configMapKeyRef parametresindeki name tanımı ile hangi ConfigMap nesnesindeki hangi key'i kullanacağımızı belirtiyoruz.

configMapKeyRef altına optional: true eklemelisiniz.Eğer ConfigMap içinde çok fazla config mevcutsa bu şekilde tek tek eklemek zor olacaktır. Bunu çözmek için ConfigMap içindeki tüm configleri envFrom ile tek seferde environment olarak ayarlayabilirsiniz.
spec:
containers:
- name: my-container
image: my-image
envFrom:
- prefix: CONFIG_
configMapKeyRef:
name: my-configmap prefix parametresi opsiyoneldir. Kullandığınızda environment variable eklerken tüm configlerin başına prefix'teki değeri ekler. Eğer ConfigMap içindeki configlerde geçersiz bir environment variable key varsa, örneğin my-key, bu geçersiz keyler eklenmez ve atlanır. Bu örnekte, environment variable'lar - karakterini kabul etmediği için eklenmez.
Ayrıca environment variable olarak geçtiğiniz configleri Pod args parametresinde de kullanabilirsiniz.
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: my-image
env:
- name: KEY1
valueFrom:
configMapKeyRef:
name: my-configmap
key: key1
args: ["${KEY1}"]Aşağıdaki şemada akışı görebilirsiniz.

1.2.2 Config Dosyası Olarak Volume İçinde Kullanmak
Configleri environment variables olarak Pod'lara dahil etmek genelde kısa configler için mantıklıdır. Fakat uzun bir değere sahip (application.properties vb.) configleriniz olduğunda environment variables yerine configMap kullanmak daha doğru bir yaklaşımdır.
configMap , ConfigMap içindeki herbir config'i bir dosya olarak belirtilen dizine kaydeder. Örneğin my-nginx-config.conf ve sleep-interval isimli dosyalarda config değerleri saklayan configmap-files isimli bir config dizinimiz mevcut olsun.

my-nginx-config.conf isimli dosya içerği ise basit bir nginx.conf yapılandırması tutsun.
server {
listen 80;
server_name www.kubia-example.com;
gzip on;
gzip_types text/plain application/xml;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}Bu dizindeki dosyalardan kubectl create configmap fortune-config --from-file=configmap-files komutu ile kolaylıkla bir ConfigMap oluşturabiliriz.
Ardından bir Pod ile bu configleri kullanabilmek için göreceğiniz üzere environment variable kullanmak mantıklı değildir. Çünkü dosya içeriğimiz çok uzun. Bu nedenle bir configMap tipinde Config Volume oluşturarak tüm bu configleri ilgili dizine mount edebiliriz.
apiVersion: v1
kind: Pod
metadata:
name: fortune-configmap-volume
spec:
containers:
- image: nginx:alpine
name: web-server
volumeMounts:
- name: config
mountPath: /etc/nginx/conf.d
readOnly: true
volumes:
- name: config
configMap:
name: fortune-configArtık Pod oluşturulduğunda fortune-config isimli ConfigMap içindeki tüm configler birer dosya olarak /etc/nginx/conf.d dizinine mount edilecektir.

Mount ettiğimiz dizinde ls /etc/nginx/conf.d komutunu çalıştırırsak ConfigMap içinde yer alan iki configi de görebiliriz.
$ ls /etc/nginx/conf.d
my-nginx-config.conf
sleep-intervalFakat ConfigMap içinde mount ettiğiniz dizine koymak istemeyeceğiniz configler olabilir. Mesela yukarıdaki örnekte sleep-interval isimli config dosyasının nginx için hiçbir önemi yoktur. Bunun önüne geçebilmek için sadece eklemek istediğiniz configleri aşağıdaki gibi seçebilirsiniz.
volumes:
- name: config
configMap:
name: fortune-config
items:
- key: my-nginx-config.conf
path: nginx.confBöylece ConfigMap içinde yer alan sadece my-nginx-config.conf isimli dosya nginx.conf dosya ismiyle mount edilen dizine eklenecektir.
Yukarıdaki uyarıdaki davranış Volume'lerin normal davranışıdır. Mount ettiğiniz dizin doluysa, bu dosyalar artık erişilimez hale gelir ve sadece Volume'un içindeki dosyalar gözükür.
Kubernetes ile bunu engellemenin bir yolu mevcuttur. Mount ettiğiniz dizindeki dosyaları erişilimez hale getirmeden subPath parametresi ile sadece kendi config dosyalarınızı ekleyebilirsiniz.
spec:
containers:
- image: some/image
volumeMounts:
- name: myvolume
mountPath: /etc/someconfig.conf
subPath: myconfig.confBu örnekte, mount edilen dizindeki dosyalar hem erişilebilir halde kalacak, hemde ConfigMap içindeki configinizi ek bir dosya olarak ilgili dizine ekleyebileceksiniz.

Ayrıca config dosyalarınızı mount ederken isterseniz dosya izinlerini de ayarlayabilirsiniz.
volumes:
- name: config
configMap:
name: my-configmap
defaultMode: "6600"Son olarak tüm volume'u mount ettikten sonra, kubectl edit configmap komutuyla bir ConfigMap içindeki config değerini güncellediğinizde, mount ettiğiniz dizindeki config dosyasının da içeriği değişir.
Fakat tüm volume yerine subPath ile sadece belirli dosyaları mount ederseniz, ConfigMap değerlerini güncelleseniz bile mount ettiğiniz dizindeki config dosyaları güncellenmeyecektir.
nginx.conf içeriğini değiştirdikten sonra nginx uygulamasının bu conf değişikliğini algılaması için nginx -s reload komutunu çalıştırmalısınız.2. Secret Nedir?
Secret, hassas bilgilerin (örneğin, parolalar, API anahtarları, sertifikalar vb.) depolanması ve yönetimi için kullanılan bir Kubernetes nesnesidir. Secret'lar ConfigMap'lerle benzer şekilde çalışır, ancak veriler şifrelenir ve daha güvenli bir şekilde saklanır. Secret'lar da YAML formatında tanımlanır ve genellikle Base64 kodlaması kullanılarak veriler depolanır. Uygulama pod'larına Secret'ları enjekte ederek, bu hassas bilgilere güvenli bir şekilde erişebilirsiniz.
ConfigMap ile Secret arasındaki önemli farklardan birisi Secret'ların bazı tiplere sahip olmasıdır. Bu tiplere şimdi bakalım.
Secret oluştururken type değeri aşağıdaki değerlerden birini alabilir:
Opaque:Opaque(generic), genel amaçlı bir Secret tipidir ve varsayılan değeridir. Bu tip, herhangi bir metin veya binary veriyi şifrelemeksizin saklamak için kullanılır. Örneğin, parolalar, sertifikalar, özel anahtarlar gibi hassas bilgiler bu Secret tipiyle saklanabilir.kubernetes.io/basic-auth:basic-auth, kullanıcı adı ve parolayı saklamak için kullanılan bir Secret tipidir. Bu tip, bir kullanıcının kimlik doğrulama bilgilerini depolamak için kullanılabilir.kubernetes.io/ssh-auth:ssh-auth, SSH kimlik doğrulama bilgilerini saklamak için kullanılan bir Secret tipidir. Bu tip, SSH sunucusuna erişim sağlamak için kullanılan kullanıcı adı ve private key bilgilerini içerebilir.kubernetes.io/tls:tls, TLS sertifikalarını ve private key'i saklamak için kullanılan bir Secret tipidir. Bu tip, HTTPS trafiğini şifrelemek veya uygulamalar arasında güvenli iletişim sağlamak için kullanılan sertifikaları içerebilir.kubernetes.io/service-account-token:service-account-token, Kubernetes Service hesabına ait kimlik bilgilerini içeren bir Secret tipidir. Bu Secret tipi, Kubernetes tarafından otomatik olarak oluşturulur ve Service hesaplarına ilişkin JWT (JSON Web Token) ve diğer yetkilendirme bilgilerini içerir.kubernetes.io/dockercfg:dockercfg, Docker Registry'lerine kimlik doğrulama yapmak için kullanılan bir Secret tipidir. Bu tip, Docker imajlarını private registry'den çekmek için gereken kimlik bilgilerini içerebilir.kubernetes.io/dockerconfigjson:dockerconfigjson, Docker imajını private registry'den çekmek için kullanılan bir Secret tipidir. Bu tip, Docker Hub veya başka bir özel Docker Registry'sindeki kimlik doğrulama bilgilerini içerir.
Bu type değerleri, Secret'lerin kullanım amaçlarına göre farklılaşmasını sağlar ve Kubernetes tarafından doğru şekilde yorumlanmalarını sağlar. Secret oluştururken doğru type değerini belirtmek, Secret'in amacına uygun olarak kullanılmasını sağlar.
2.1. Secret Nasıl Oluşturulur?
Kubernetes'te Secret oluşturmak için hem YAML hem de kubectl komutunu kullanabilirsiniz. Her iki yönteme de bakalım.
2.1.1 YAML Manifest Dosyasıyla Secret Oluşturmak
YAML manifest dosyasıyla Secret oluşturmak için aşağıdaki örneği kullanabilirsiniz.
apiVersion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque
data:
username: dXNlcm5hbWU=
password: cGFzc3dvcmQ=
stringData:
blog: Kerteriz Blogdataparametresi alanında tüm key-value config çiftlerinizi oluşturabilirsiniz. Config değerleri Base64 ile encode edilerek eklenmelidir. Çünkü eklemek istediğiniz değerler binary data içeriyor olabilirstringDataparametresi altında ise Base64 yerine plain text değerlerinizi ekleyebilirsiniz.
Bu YAML dosyasını kullanarak Secret'ı oluşturmak için aşağıdaki komutu kullanabilirsiniz:
kubectl apply -f secret.yamlDiğer Secret tipleri için kullanabileceğiniz manifest örneklerini https://kubernetes.io/docs/concepts/configuration/secret/#secret-types adresinden inceleyebilirsiniz.
2.1.2 Kubectl Komutuyla Secret Oluşturmak
Imperative methodla kubectl komutunu kullanarak Secret oluştururken birçok seçeneğimiz mevcut. Tüm bu seçeneklere tek tek bakalım.
--from-literalargümanını kullanarak key-value config oluşturabiliriz. Tek bir komutta birden fazla config oluşturabilirsiniz.
kubectl create secret generic my-secret --from-literal=user=poweruser --from-literal=password='f0ob@r'generic adını alır.--from-fileargümanını kullanarak bir dosya içeriğinden config oluşturabilirsiniz. Eğer key belirtmezseniz, key dosya adı olarak belirlenir.
kubectl create configmap my-configmap --from-file=config-file.conf --from-file=file-config=config-file2.txt--from-fileargümanını kullanarak sadece dosya değil bir dizinde belirtebilirsiniz. Böylece o dizin altında yer alan tüm dosyalar için configler oluşturulmuş olur.
kubectl create secret generic my-secret --from-file=/var/secret-config-dir/Son olarak tüm bu yöntemleri tek bir komut içerisinde aynı anda kullanabilirsiniz. Örneğin aşağıdaki komut tüm yöntemleri aynı anda kullanmanıza olanak sağlar.
kubectl create secret generic my-secret
➥ --from-file=foo.json
➥ --from-file=bar=foobar.conf
➥ --from-file=config-opts/
➥ --from-literal=some=thing2.2. Secret Nasıl Kullanılır?
Kubernetes Secret'ları kullanarak bir Pod'un yapılandırma bilgilerini belirtmek için birkaç farklı yöntem vardır. Tüm bu methodları tek tek inceleyelim.
2.2.1 Environment Variable Olarak Kullanmak
Secret configlerini kullanmanın en basit yolu, onları environment variable olarak container'lara geçmektir. Pod konfigürasyonunda env bölümünü kullanarak valueFrom parametresi ile nasıl environment variable tanımlayabileceğimizi aşağıdaki örnekte görebilirsiniz.
apiVersion: v1
kind: Pod
metadata:
name: my-web
spec:
containers:
- image: nginx
name: web
env:
- name: password
valueFrom:
secretKeyRef:
name: my-secret
key: password2.2.2 Config Dosyası Olarak Volume İçinde Kullanmak
Configleri environment variables yerine secret kullanarak bir volume içine de çıkarabilirsiniz.
apiVersion: v1
kind: Pod
metadata:
name: my-web
spec:
containers:
- image: nginx:alpine
name: web-server
volumeMounts:
- name: certs
mountPath: /etc/nginx/certs/
readOnly: true
volumes:
- name: certs
secret:
secretName: my-secret2.3. Docker Hub Private Repository için Secret Kullanımı
Bu konu ile çok kez karşılaşacağınız için özel bir başlık oluşturduk. Eğer Docker Hub üzerinde yer alan private bir image repository (registry) üzerinden image pull etmeniz gerekirse öncelikle imagePullSecrets ile gerekli authentication işlemini ayarlamanız gerekir.
Docker registry için Secret tiplerindeki özel docker-registry tipini kullanacağız. Öncelikle bu tipi kullanarak credentials bilgilerimizi içeren bir secret oluşturalım.
kubectl create secret docker-registry mydockerhubsecret \
--docker-username=myusername --docker-password=mypassword \
[email protected]generic tipte bir secret oluşturmak yerine, mydockerhubsecret adında bir docker-registry tipinde secret oluşturduk ve Docker Hub kullanıcı adını, şifreni ve e-postasını belirttik. Yeni oluşturulan Secret'ın içeriğini kubectl define ile incelerseniz, .dockercfg adında tek bir girdi içerdiğini görürsünüz. Bu, ana dizininizdeki docker login komutunu çalıştırdığınızda Docker tarafından oluşturulan .dockercfg dosyasına eşdeğerdir.
Artık private repository'den pull edeceğiniz pod'u kullanacağınız manifest dosyasında bu secret'ı imagePullSecrets değişkeni ile ekleyebilirsiniz:
apiVersion: v1
kind: Pod
metadata:
name: private-pod
spec:
imagePullSecrets:
- name: mydockerhubsecret
containers:
- image: username/private:tag
name: mainSıradaki yazı ile eğitim serisine devam edebilirsiniz.
